package com.yfjin.camera2;


import android.util.Log;

/**
 * YUV_420_SP = NV12     yyyy yyyy uv uv
 * NV21                   yyyy yyyy vu vu
 * <p>
 * Camera2使用ImageReader进行数据回调，但使用YUV_420_888格式，回调后yuv分别存储成plane数组中的3个
 * 如果要形成nv21或i420数据，需要重新组合起来
 */


public class ImageUtil {


    public static void yuv888ToNv12_1(byte[] y, byte[] u, byte[] v, byte[] nv12, int stride, int height) {
        System.arraycopy(y, 0, nv12, 0, y.length);
        // 注意，若length值为 y.length * 3 / 2 会有数组越界的风险，需使用真实数据长度计算

        //420 4:1:1
        //U和V一半的数据是可以丢弃的，原先是8:8:8 现在要改成 8:2:2

//        int length = y.length + u.length / 2 + v.length / 2;
        int uIndex = 0, vIndex = 0;

        Log.i("123123", "stride * height:" + stride + "*" + height + ":" + stride * height);
        Log.i("123123", "y:" + y.length + "-u:" + u.length + "-v:" + v.length);
        Log.i("123123", "nv12.length:" + nv12.length);
        int ll = y.length + u.length / 2 + v.length / 2;
        Log.i("123123", "length:" + ll);
        int count = 0;
        //因为一次填充一组U和V，所以除以2
//        int lenght=y.length+(u.length+v.length)/2;
        int lenght = stride * height + (u.length + v.length) / 2;
//        int lenght=stride * height+(u.length+v.length)/2;
        for (int i = stride * height; i < lenght; i += 2) {
            //这里不能用y.length，因为要对齐，用stride * height开始，比y.lenght大，空出来部分的是空数据填补
//        for (int i = y.length; i < nv12.length - 2; i += 2) {
            nv12[i] = u[uIndex];
            nv12[i + 1] = v[vIndex];
            uIndex += 2;
            vIndex += 2;
            count++;
        }
        Log.i("123123", "count:" + count);
//        throw new NullPointerException();
    }

    //==========================================================================================
    //=============================以下都没用到===================================================
    //==========================================================================================

    public static void yuv888ToNv12_2(byte[] y, byte[] u, byte[] v, byte[] nv12, int stride, int height) {
        System.arraycopy(y, 0, nv12, 0, y.length);
        System.arraycopy(u, 0, nv12, y.length, u.length);
//        throw new NullPointerException();
    }


    //    nv21ToNV12
    public static void yuv888ToNv12_0(byte[] y, byte[] u, byte[] v, byte[] nv21, int stride, int height) {
        System.arraycopy(y, 0, nv21, 0, y.length);
        // 注意，若length值为 y.length * 3 / 2 会有数组越界的风险，需使用真实数据长度计算
        int length = y.length + u.length / 2 + v.length / 2;
        int uIndex = 0, vIndex = 0;
        for (int i = stride * height; i < length; i += 2) {
            nv21[i] = u[uIndex];
            nv21[i + 1] = v[vIndex];
            vIndex += 2;
            uIndex += 2;
        }
    }
//滴滴 小问题
//

    public static byte[] nv21_rotate_to_90(byte[] nv21_data, byte[] nv21_rotated, int srcLieWidth, int srcHangHeight) {

        Log.i("223223","nv21_data:"+nv21_data.length+"-"+nv21_rotated.length);
        Log.i("223223","srcLieWidth-srcHangHeight:"+srcLieWidth+"-"+srcHangHeight);
        Log.i("223223","srcLieWidth*srcHangHeight:"+srcLieWidth*srcHangHeight);

        byte[][] temp_src = new byte[srcHangHeight][srcLieWidth];
        byte[][] temp_dst = new byte[srcLieWidth][srcHangHeight];


        for (int i = 0; i < srcHangHeight; i++) {
            for (int j = 0; j < srcLieWidth; j++) {
                temp_src[i][j] = nv21_data[i * srcLieWidth + j];
            }
        }

        for (int i = 0; i < srcLieWidth; i++) {
            int heightOffset = srcHangHeight - 1;
            for (int j = 0; j < srcHangHeight; j++) {
                temp_dst[i][j] = temp_src[heightOffset][i];
                heightOffset--;
            }
        }

        int count=0;
        for (int i = 0; i < srcLieWidth; i++) {
            for (int j = 0; j < srcHangHeight; j++) {
                nv21_rotated[i * srcHangHeight + j] = temp_dst[i][j];
                count++;
            }
        }

        Log.i("223223","count:"+count);

        return nv21_rotated;
    }

    public static byte[] nv21_rotate_to_90_0(byte[] nv21_data, byte[] nv21_rotated, int width, int height) {

        Log.i("223223", "w-h:" + width + "-" + height);

        int y_size = width * height;
        int buffser_size = nv21_data.length;

        // Rotate the Y luma
        int i = 0;
        int startPos = (height - 1) * width;
        for (int x = 0; x < width; x++) {
            int offset = startPos;
            for (int y = height - 1; y >= 0; y--) {
                nv21_rotated[i] = nv21_data[offset + x];
                i++;
                offset -= width;
            }
        }
        // Rotate the U and V color components
        i = buffser_size - 1;
        for (int x = width - 1; x > 0; x = x - 2) {
            int offset = y_size;
            for (int y = 0; y < height / 2; y++) {
                nv21_rotated[i] = nv21_data[offset + x];
                i--;
                nv21_rotated[i] = nv21_data[offset + (x - 1)];
                i--;
                offset += width;
            }
        }
        return nv21_rotated;
    }

    //3/2    2   1
    public static byte[] nv21toNV12(byte[] nv21, byte[] nv12) {
        int size = nv21.length;
        nv12 = new byte[size];
        int len = size * 2 / 3;
        System.arraycopy(nv21, 0, nv12, 0, len);

        int i = len;
        while (i < size - 1) {
            nv12[i] = nv21[i + 1];
            nv12[i + 1] = nv21[i];
            i += 2;
        }
        return nv12;
    }


    public static byte[] ni(int width, int height, byte[] src) {
        byte[] des = new byte[width * height * 3 / 2];

        int nWidth = 0, nHeight = 0;
        int wh = 0;
        int uvHeight = 0;
        if (width != nWidth || height != nHeight) {
            nWidth = width;
            nHeight = height;
            wh = width * height;
            uvHeight = height >> 1;//uvHeight = height / 2
        }
        //旋转Y
        int k = 0;
        for (int i = 0; i < width; i++) {
            int nPos = width - 1;
            for (int j = 0; j < height; j++) {
                des[k] = src[nPos - i];
                k++;
                nPos += width;
            }
        }

        for (int i = 0; i < width; i += 2) {
            int nPos = wh + width - 1;
            for (int j = 0; j < uvHeight; j++) {
                des[k] = src[nPos - i - 1];
                des[k + 1] = src[nPos - i];
                k += 2;
                nPos += width;
            }
        }
        return des;
    }
}
